/****************************** Module Header ******************************\
 * Module Name:  mxString.cs
 * Module Version:  1.0.0 (2011-9-28)
 * Copyright (c) AnyEB.Com (14507247@qq.com)
 * 
 * This class is used to extension String instance's method.  It supplies 
 * useful extension methods, such as ParseToBoolean().
 * 
 * This source is subject to the GPL License.
 * See http://www.gnu.org/licenses/gpl.html.
 * All other rights reserved.
 * 
 * THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, 
 * EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED 
 * WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
\***************************************************************************/

using System;
using System.Linq;
using System.Data;
using System.Collections.Generic;
using System.Text;
using UCL.Security.Cryptography;

namespace UCL
{
    /// <summary>
    /// 字符串对象的扩展类
    /// <para>提供字符串实例的扩展方法，如语义验证、字符串和其他值类型的转换、字符串重复、地址栏链接串联等</para>
    /// </summary>
    /// <remarks>
    /// <para>2011-9-28 by sutroon created</para>
    /// <para>2015-1-28 by sutroon 迁移一些方法到BizUtil</para>
    /// </remarks>
    public static class mxString
    {
        #region 字符串业务验证模块
        /// <summary>
        /// 判断是否是有效的电子邮件地址
        /// </summary>
        /// <param name="Email"></param>
        /// <returns></returns>
        public static bool IsValidEmail(this string Email)
        {
            return RegExp.IsMatch(Email, RegExp.Rules.Email.Express);
        }

        /// <summary>
        /// 判断是否是有效的手机号码
        /// </summary>
        /// <param name="MobileNumber"></param>
        /// <returns></returns>
        public static bool IsValidMobileNumber(this string MobileNumber)
        {
            return RegExp.IsMatch(MobileNumber, RegExp.Rules.MobileNumber.Express);
        }

        /// <summary>
        /// 判断是否是有效的数字
        /// </summary>
        /// <param name="Number"></param>
        /// <returns></returns>
        public static bool IsValidNumber(this string Number)
        {
            return RegExp.IsMatch(Number, RegExp.Rules.Number.Express);
        }

        /// <summary>
        /// 判断是否是IP地址格式 0.0.0.0
        /// </summary>
        /// <param name="ip"></param>
        /// <returns></returns>
        public static bool IsValidIPAddress(this string ip)
        {
            if (ip == null || ip == string.Empty || ip.Length < 7 || ip.Length > 15) return false;
            return RegExp.IsMatch(ip, RegExp.Rules.IP.Express);
        }

        /// <summary>
        /// 判断是否是有效的URL
        /// </summary>
        /// <param name="url"></param>
        /// <returns></returns>
        public static bool IsValidURL(this string url)
        {
            if (url == null || url.Length == 0) return false;
            return RegExp.IsMatch(url, RegExp.Rules.URL.Express);
        }

        /// <summary>
        /// 判断是否是有效的身份证
        /// </summary>
        /// <param name="IDCardNumber"></param>
        /// <returns></returns>
        public static bool IsValidIdCardNumber(this string IDCardNumber)
        {
            return RegExp.IsMatch(IDCardNumber, RegExp.Rules.IdentityCardNumber.Express);
        }

        /// <summary>
        /// 判断是否是有效的图片
        /// </summary>
        /// <param name="v"></param>
        /// <returns></returns>
        public static bool IsValidImageFile(this string v)
        {
            if (v == null || v.IndexOf('.') == -1) return false;
            string sExt = System.IO.Path.GetExtension(v).ToLower() + ".";
            return (".jpg.jpeg.png.gif.bmp.tiff.".IndexOf(sExt) >= 0);
        }
        #endregion

        /// <summary>
        /// 检测字符串类型
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="s"></param>
        /// <returns></returns>
        public static bool IsType<T>(this string s)
        {
            if (s.Length == 0) return false;
            if (typeof(T) == typeof(string))
            {
                return (s.Length > 0);
            }
            if (typeof(T) == typeof(DateTime))
            {
                DateTime o;
                return DateTime.TryParse(s, out o);
            }
            if (typeof(T) == typeof(int))
            {
                int o;
                return int.TryParse(s, out o);
            }
            if (typeof(T) == typeof(short))
            {
                short o;
                return short.TryParse(s, out o);
            }
            if (typeof(T) == typeof(double))
            {
                double o;
                return double.TryParse(s, out o);
            }
            if (typeof(T) == typeof(bool))
            {
                bool o;
                return (bool.TryParse(s, out o));
            }
            if (typeof(T) == typeof(decimal))
            {
                decimal o;
                return decimal.TryParse(s, out o);
            }
            return false;
        }

        /// <summary>
        /// 检测字符串是否是有效的参数
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="s"></param>
        /// <param name="msgCollection"></param>
        /// <param name="errTip"></param>
        /// <param name="minLength"></param>
        /// <param name="maxLength"></param>
        /// <returns></returns>
        public static bool IsValidParameter<T>(this string s, ref Dictionary<string, string> msgCollection, string errTip, int minLength = 1, int maxLength = 0)
        {
            string sKey = (msgCollection.Count + 1).ToString();
            // !@c 2013-2-21
            if (string.IsNullOrEmpty(s))
            {
                msgCollection.Add(sKey, "参数不能为空");
                return false;
            }
            if (s.IndexOf('\'') > -1)
            {
                msgCollection.Add(sKey, "参数中包含非法关键字");
                return false;
            }
            if (typeof(T) == typeof(string))
            {
                if ((minLength > 0 && s.Length < minLength) || (maxLength > 0 && s.Length > maxLength))
                {
                    msgCollection.Add(sKey, errTip);
                    return false;
                }

            }
            bool blnR = s.IsType<T>();
            if (!blnR) msgCollection.Add(sKey, errTip);
            return blnR;
        }
        public static bool IsValidParameter<T>(this string s)
        {
            if (typeof(T) == typeof(string)) return !(string.IsNullOrEmpty(s) || s.IndexOf("'") > -1);
            return s.IsType<T>();
        }

        /// <summary>
        /// 检测是否包含非法Sql字符[2013-7-12 by sutroon]
        /// </summary>
        /// <param name="s"></param>
        /// <param name="check"></param>
        /// <returns></returns>
        public static string CheckSqlSafe(this string s, bool check = false)
        {
            return (check && s.IndexOf('\'') > -1) ? s.Replace("'", "") : s;
        }

        #region 带消息输出的字符串转换
        /// <summary>
        /// 字符串转换字符串值，如果转换失败添加一个错误消息
        /// </summary>
        /// <param name="Value"></param>
        /// <param name="MessageSet"></param>
        /// <param name="MessageItem">new string[]{"title","标题未填写"}</param>
        /// <returns></returns>
        public static string ConvertToString(this string Value, ref Dictionary<string, string> MessageSet, params string[] MessageItem)
        {
            if (Value == null || Value.Length == 0)
            {
                Value = "";
                MessageSet[MessageItem[0]] = MessageItem[1];
            }
            return Value;
        }
        /// <summary>
        /// 字符串转换数字值，如果转换失败添加一个错误消息
        /// </summary>
        /// <param name="Value"></param>
        /// <param name="MessageSet"></param>
        /// <param name="MessageItem"></param>
        /// <returns></returns>
        public static int ConvertToInteger(this string Value, ref Dictionary<string, string> MessageSet, params string[] MessageItem)
        {
            int iOut = 0;
            if (!Int32.TryParse(Value, out iOut)) MessageSet[MessageItem[0]] = MessageItem[1];
            return iOut;
        }
        /// <summary>
        /// 字符串转换双字节值，如果转换失败添加一个错误消息
        /// </summary>
        /// <param name="Value"></param>
        /// <param name="MessageSet"></param>
        /// <param name="MessageItem"></param>
        /// <returns></returns>
        public static double ConvertToDouble(this string Value, ref Dictionary<string, string> MessageSet, params string[] MessageItem)
        {
            double dblOut = 0.00;
            if (!Double.TryParse(Value, out dblOut)) MessageSet[MessageItem[0]] = MessageItem[1];
            return dblOut;
        }
        /// <summary>
        /// 字符串转换时间值，如果转换失败添加一个错误消息
        /// </summary>
        /// <param name="Value"></param>
        /// <param name="MessageSet"></param>
        /// <param name="MessageItem"></param>
        /// <returns></returns>
        public static DateTime ConvertToDateTime(this string Value, ref Dictionary<string, string> MessageSet, params string[] MessageItem)
        {
            DateTime datOut = DateTime.Parse("1900-1-1");
            if (!DateTime.TryParse(Value, out datOut)) MessageSet[MessageItem[0]] = MessageItem[1];
            return datOut;
        }
        /// <summary>
        /// 字符串转换布尔值，如果转换失败添加一个错误消息
        /// </summary>
        /// <param name="Value"></param>
        /// <param name="MessageSet"></param>
        /// <param name="MessageItem"></param>
        /// <returns></returns>
        public static bool ConvertToBoolean(this string Value, ref Dictionary<string, string> MessageSet, params string[] MessageItem)
        {
            bool blnOut = false;
            if (!Boolean.TryParse(Value, out blnOut)) MessageSet[MessageItem[0]] = MessageItem[1];
            return blnOut;
        }
        #endregion

        #region 字符串安全类型转换

        /// <summary>
        /// 确保值不为空
        /// </summary>
        /// <param name="s"></param>
        /// <param name="defv"></param>
        /// <returns></returns>
        public static string NotNull(this string s, string defv = "")
        {
            return null == s ? defv : s;
        }

        /// <summary>
        /// 字符串转换为布尔值
        /// </summary>
        /// <param name="v"></param>
        /// <returns></returns>
        /// <remarks>2014-4-9 新增success</remarks>
        public static bool ToBoolean(this string v)
        {
            return !string.IsNullOrWhiteSpace(v) && new string[] { "true", "right", "1", "yes", "ok", "success" }.Contains(v.ToLower());
        }

        /// <summary>
        /// 字符串转换为数字
        /// </summary>
        /// <param name="v"></param>
        /// <returns></returns>
        public static int ToInt(this string v, int defv = 0)
        {
            if (string.IsNullOrEmpty(v)) return defv; // 修复null值出错的问题(2014-1-17)
            if (v.Contains('.')) v = v.Substring(0, v.IndexOf('.')); // 修复浮点转换成0的问题
            int i;
            return Int32.TryParse(v, out i) ? i : defv;
        }

        /// <summary>
        /// 字符串转换为数字(short)
        /// </summary>
        /// <param name="v"></param>
        /// <returns></returns>
        public static short ToShort(this string v, short defv = 0)
        {
            if (string.IsNullOrEmpty(v)) return defv; // 修复null值出错的问题(2014-1-17)
            if (v.Contains('.')) v = v.Substring(0, v.IndexOf('.')); // 修复浮点转换成0的问题
            short s;
            return short.TryParse(v, out s) ? s : defv;
        }

        /// <summary>
        /// 字符串转换为数字(double)
        /// </summary>
        /// <param name="v"></param>
        /// <returns></returns>
        public static double ToDouble(this string v, double defv = 0.00)
        {
            if (string.IsNullOrEmpty(v)) return defv; // 修复null值出错的问题(2014-1-17)
            double d;
            return double.TryParse(v, out d) ? d : defv;
        }

        /// <summary>
        /// 字符串转换为货币
        /// </summary>
        /// <param name="v"></param>
        /// <returns></returns>
        public static decimal ToDecimal(this string v, decimal defv = 0.00m)
        {
            if (string.IsNullOrEmpty(v)) return defv; // 修复null值出错的问题(2014-1-17)
            decimal d;
            return decimal.TryParse(v, out d) ? d : defv;
        }

        public static float ToFloat(this string v, float defv = 0.0f)
        {
            if (string.IsNullOrEmpty(v)) return defv; // 修复null值出错的问题(2014-1-17)
            float f;
            return Single.TryParse(v, out f) ? f : defv;
        }

        /// <summary>
        /// 字符串转换为时间
        /// </summary>
        /// <param name="v"></param>
        /// <returns></returns>
        public static DateTime ToDateTime(this string v, DateTime defv)
        {
            if (string.IsNullOrEmpty(v)) return defv; // 修复null值出错的问题(2014-1-17)
            DateTime d;
            return (DateTime.TryParse(v, out d)) ? d : defv;
        }
        public static DateTime ToDateTime(this string v)
        {
            return v.ToDateTime(DateTime.Parse("1900-1-1"));
        }

        /// <summary>
        /// 更新时间的日期部分
        /// </summary>
        /// <param name="dt"></param>
        /// <param name="date"></param>
        /// <returns></returns>
        /// <remarks>2014-1-24 sutroon</remarks>
        public static DateTime UpdateDate(this DateTime dt, string date)
        {
            return DateTime.Parse(date + " " + dt.ToString("HH:mm:ss"));
        }

        /// <summary>
        /// 更新时间的时间部分
        /// </summary>
        /// <param name="dt"></param>
        /// <param name="time"></param>
        /// <returns></returns>
        /// <remarks>2014-1-24 sutroon</remarks>
        public static DateTime UpdateTime(this DateTime dt, string time)
        {
            return DateTime.Parse(dt.ToString("yyyy-MM-dd") + " " + time);
        }

        /// <summary>
        /// 字符串转换为Guid
        /// </summary>
        /// <param name="v"></param>
        /// <returns></returns>
        public static Guid ToGuid(this string v)
        {
            if (string.IsNullOrEmpty(v)) return Guid.Empty; // 修复null值出错的问题(2014-1-17)
            Guid g;
            return Guid.TryParse(v, out g) ? g : Guid.Empty;
        }

        /// <summary>
        /// 字符串转换为XElement对象
        /// </summary>
        /// <param name="v"></param>
        /// <returns></returns>
        public static System.Xml.Linq.XElement ToXElement(this string v)
        {
            return System.Xml.Linq.XElement.Parse(v);
        }
        #endregion

        #region 字符串处理

        /// <summary>
        /// 标签头部显示数量
        /// </summary>
        /// <param name="s"></param>
        /// <param name="c"></param>
        /// <param name="symbol1"></param>
        /// <param name="symbol2"></param>
        /// <returns></returns>
        public static string UpdateCountText(this string s, int c, string symbol1 = "(", string symbol2 = ")")
        {
            int a = s.IndexOf(symbol1);
            return "{0}{2}{1}{3}".Fmt(a > -1 ? s.Substring(0, a) : s, c, symbol1, symbol2);
        }

        /// <summary>
        /// 重复字符串
        /// </summary>
        /// <param name="s"></param>
        /// <param name="Count"></param>
        /// <returns></returns>
        public static string Repeat(this string s, int Count)
        {
            int i = 1;
            string strOut = "";
            while (i <= Count)
            {
                strOut += s;
                i++;
            }
            return strOut;
        }

        /// <summary>
        /// 获取指定字符串的匹配次数
        /// </summary>
        /// <param name="s"></param>
        /// <param name="compare"></param>
        /// <returns></returns>
        public static int MatchCount(this string s, string compare)
        {
            if (s == null || s.Length == 0) return 0;
            compare = compare.Replace(".", "\\.");
            return RegExp.Match(s, compare).Count;
        }

        /// <summary>
        /// 截取指定长度的字符串，区分单字节和双字节长度
        /// </summary>
        /// <param name="s"></param>
        /// <param name="startIndex"></param>
        /// <param name="length"></param>
        /// <returns></returns>
        public static string SubText(this string s, int startIndex, int length)
        {
            if (s == null) return "";
            if (length == 0) return s;
            int i = 0;
            int count = 0;
            foreach (char item in s)
            {
                i += (RegExp.IsMatch(item.ToString(), @"[\x00-\xff]+")) ? 1 : 2;
                if (i <= length)
                {
                    count++;
                }
                else
                {
                    return s.Substring(startIndex, count);
                }
            }
            return s;
        }

        /// <summary>
        /// 移除尾部节点字符串
        /// </summary>
        /// <param name="s"></param>
        /// <param name="splitor"></param>
        /// <param name="count"></param>
        /// <returns></returns>
        public static string TrimNodeEnd(this string s, string splitor, int count)
        {
            if (string.IsNullOrEmpty(s)) return "";
            if (s.IndexOf(splitor) == -1) return s;
            while (count > 0)
            {
                s = s.Substring(0, s.LastIndexOf(splitor));
                count--;
            }
            return s;
        }

        /// <summary>
        /// 移除头部节点字符串
        /// </summary>
        /// <param name="s"></param>
        /// <param name="splitor"></param>
        /// <param name="count"></param>
        /// <returns></returns>
        public static string TrimNodeStart(this string s, string splitor, int count)
        {
            if (string.IsNullOrEmpty(s)) return string.Empty;
            if (s.IndexOf(splitor) == -1) return s;
            while (count > 0)
            {
                s = s.Substring(s.IndexOf(splitor) + 1);
                count--;
            }
            return s;
        }

        /// <summary>
        /// 补齐右边
        /// </summary>
        /// <param name="s"></param>
        /// <param name="padding"></param>
        /// <returns></returns>
        public static string PadRight(this string s, string padding)
        {
            if (s == null || s.Length == 0) return padding;
            if (s.Length < padding.Length) return s + padding;
            if (s.Substring(s.Length - padding.Length) == padding) return s;
            return s + padding;
        }

        /// <summary>
        /// 将字符串分割到字典对象中
        /// </summary>
        /// <param name="s"></param>
        /// <param name="splitGroup"></param>
        /// <param name="splitNameValue"></param>
        /// <returns></returns>
        public static Dictionary<string, string> ToDictionary(this string s, string splitGroup = "&", string splitNameValue = "=")
        {
            Dictionary<string, string> oDict = new Dictionary<string, string>();
            if (string.IsNullOrEmpty(s)) return oDict;
            string[] arrItem;
            foreach (string strGroup in s.Split(splitGroup.ToCharArray()))
            {
                arrItem = strGroup.Split(splitNameValue.ToCharArray());
                if (arrItem.Length == 2)
                {
                    if (!oDict.ContainsKey(arrItem[0])) oDict.Add(arrItem[0], arrItem[1]);
                }
            }
            return oDict;
        }

        /// <summary>
        /// 将字符串分割到数据表对象中
        /// </summary>
        /// <param name="s"></param>
        /// <param name="splitGroup"></param>
        /// <param name="splitNameValue"></param>
        /// <returns></returns>
        public static DataTable ToDataTable(this string s, string splitGroup = "&", string splitNameValue = "=")
        {
            DataTable dt = new DataTable();
            if (string.IsNullOrEmpty(s)) return dt;
            string[] arrGroup = s.Split(splitGroup.ToCharArray());
            for (int i = 0; i < arrGroup.Length; i++)
            {
                dt.Columns.Add("col" + i);
            }
            foreach (string strGroup in arrGroup)
            {
                dt.Rows.Add(strGroup.Split(splitNameValue.ToCharArray()));
            }
            return dt;
        }

        /// <summary>
        /// 匹配DataTable.ToText()方法
        /// <para>2013-8-6 by sutroon</para>
        /// </summary>
        /// <param name="s"></param>
        /// <param name="colSplitor"></param>
        /// <param name="rowSplitor"></param>
        /// <param name="skipFirstRow"></param>
        /// <param name="showRowHeader"></param>
        /// <returns></returns>
        public static DataTable ToDataTableByText(this string s, string colSplitor = " | ", string rowSplitor = "\r\n", bool skipFirstRow = false, bool showRowHeader = false)
        {
            DataTable dt = new DataTable();
            string[] arr = s.Split(new string[] { rowSplitor }, StringSplitOptions.RemoveEmptyEntries);
            string[] arrRow = arr[0].Split(new string[] { colSplitor }, StringSplitOptions.None);
            foreach (string c in arrRow)
            {
                dt.Columns.Add(c);
            }
            bool first = true;
            foreach (string r in arr)
            {
                if (first)
                {
                    first = false;
                    continue;
                }
                arrRow = r.Split(new string[] { colSplitor }, StringSplitOptions.None);
                dt.Rows.Add(arrRow);
            }
            return dt;
        }

        /// <summary>
        /// 模拟string.Format()方法格式化格式字符串
        /// </summary>
        /// <param name="s"></param>
        /// <param name="args"></param>
        /// <returns></returns>
        public static string Fmt(this string s, params object[] args)
        {
            return string.IsNullOrEmpty(s) ? string.Empty : string.Format(s, args);
        }

        /// <summary>
        /// 被格式化到{0}
        /// </summary>
        /// <param name="s"></param>
        /// <param name="tpl"></param>
        /// <returns></returns>
        public static string Fmto(this string s, string tpl)
        {
            return string.Format(tpl, s);
        }

        /// <summary>
        /// 模拟string.Format()方法格式化格式字符串
        /// <para>用户向指定的模板批量填充参数，例如生成地址栏链接等</para>
        /// <example>
        /// <![CDATA[
        ///     "<a href='{1}'>{0}</a> &raquo; ".AddArgs("首页".JoinToArray("/Default.aspx"), "需求列表".JoinToArray("###")).TrimEnd(" &raquo; ".ToCharArray());
        /// ]]>
        /// </example>
        /// </summary>
        /// <param name="s"></param>
        /// <param name="args"></param>
        /// <returns></returns>
        public static string AddArgs(this string s, params string[][] args)
        {
            StringBuilder sb = new StringBuilder();
            foreach (string[] arg in args)
            {
                sb.AppendFormat(s, arg);
            }
            return sb.ToString();
        }

        /// <summary>
        /// 连接其他字符串成为一个数组
        /// </summary>
        /// <param name="s"></param>
        /// <param name="args"></param>
        /// <returns></returns>
        public static string[] JoinToArray(this string s, params string[] args)
        {
            if (args == null) return new string[] { s };
            IList<string> list = args.ToList();
            list.Insert(0, s);
            return list.ToArray();
        }

        /// <summary>
        /// 将字符串按照指定的长度分割到数组中
        /// </summary>
        /// <param name="s"></param>
        /// <param name="length"></param>
        /// <returns></returns>
        public static string[] ToArray(this string s, int length)
        {
            return RegExp.Split(s, @".{1," + length.ToString() + "}");

        }

        /// <summary>
        /// 转换成键值数据表
        /// <para>2012-9-7</para>
        /// </summary>
        /// <param name="s"></param>
        /// <param name="splitor1"></param>
        /// <param name="splitor2"></param>
        /// <returns></returns>
        public static DataTable ToIdNameDataTable(this string s, string splitor1 = "=", string splitor2 = ";")
        {
            DataTable dt = new DataTable();
            dt.Columns.Add("ID");
            dt.Columns.Add("Name");
            string[] arr;
            foreach (string a in s.Split(splitor2.ToCharArray(), StringSplitOptions.RemoveEmptyEntries))
            {
                if (a.IndexOf(splitor1) == -1) continue;
                arr = a.Split(splitor1.ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
                dt.Rows.Add(arr[0], arr[1]);
            }
            return dt;
        }

        /// <summary>
        /// 替换键值格式的字符串中的某一对键值
        /// </summary>
        /// <param name="s"></param>
        /// <param name="key"></param>
        /// <param name="value"></param>
        /// <param name="splitor1"></param>
        /// <param name="splitor2"></param>
        /// <returns></returns>
        public static string ReplaceKeyValue(this string s, string key, string value, string splitor1 = "=", string splitor2 = "&")
        {
            // 如果是空的字符串则直接返回键值对
            if (s.Length == 0) return "{0}{1}{2}".Fmt(key, splitor1, value);

            string sTxt = "{0}{1}{2}".Fmt(splitor2, s.Trim(splitor2.ToCharArray()), splitor2);
            string sPattern = "{0}{1}{2}[^{0}]*".Fmt(splitor2, key, splitor1, splitor2);
            // 如果字串里面没有匹配的名称，则在最后加入该键值对
            if (!RegExp.IsMatch(sTxt, sPattern)) return "{0}{1}{2}{3}{4}".Fmt(s, splitor2, key, splitor1, value);

            // 如果有键值对，则更改值
            return RegExp.Replace(sTxt, sPattern, "{0}{1}{2}{3}".Fmt(splitor2, key, splitor1, value)).Trim(splitor2.ToCharArray());
        }

        /// <summary>
        /// 获取参数化字符串中指定键的值
        /// </summary>
        /// <param name="s"></param>
        /// <param name="key"></param>
        /// <param name="splitor1"></param>
        /// <param name="splitor2"></param>
        /// <returns></returns>
        public static string GetParameterValue(this string s, string key, string splitor1 = "=", string splitor2 = "&")
        {
            Dictionary<string, string> dict = s.ToDictionary(splitor2, splitor1);
            return dict.ContainsKey(key) ? dict[key] : "";
        }
        public static string UpdateParameterValue(this string s, string key, string value, string splitor1 = "=", string splitor2 = "&")
        {
            string a = "{0}{1}{2}".Fmt(key, splitor1, value);
            if (string.IsNullOrEmpty(s)) return a;
            s = RegExp.Replace(s, "{0}{1}[^{2} | $]*".Fmt(key, splitor1, splitor2), a);
            return s;
        }

        /// <summary>
        /// 批量替换
        /// </summary>
        /// <param name="s"></param>
        /// <param name="args"></param>
        /// <returns></returns>
        public static string BatchReplace(this string s, params string[] args)
        {
            if (s == null || s.Length == 0) return "";
            string sOut = "";
            foreach (string arg in args)
            {
                sOut += string.Format(s, arg);
            }
            return sOut;
        }

        /// <summary>
        /// 设置字符掩码
        /// </summary>
        /// <param name="s"></param>
        /// <param name="length"></param>
        /// <param name="startindex"></param>
        /// <param name="maskchar"></param>
        /// <returns></returns>
        public static string MaskText(this string s, int length, int startindex = -1, string maskchar = "*")
        {
            if (string.IsNullOrEmpty(s)) return string.Empty;
            if (s.Length < startindex) return s;
            int len = s.Length;
            if (startindex == -1)
            {
                if (length > len) length = len;
                return string.Format("{0}{1}", s.Substring(0, len - length), maskchar.Repeat(length));
            }
            if (startindex > -1 && len <= length) return maskchar.Repeat(len);
            int sendlen = startindex + length;
            return string.Format("{0}{1}{2}", s.Substring(0, startindex), maskchar.Repeat(length), sendlen > len ? "" : s.Substring(startindex + length));
        }

        /// <summary>
        /// 是否包含某些词汇
        /// </summary>
        /// <param name="s"></param>
        /// <param name="args"></param>
        /// <returns></returns>
        /// <remarks>2014-5-29 by sutroon</remarks>
        public static bool ContainsWords(this string s, params string[] args)
        {
            if (string.IsNullOrEmpty(s)) return false;
            foreach (string a in args)
            {
                if (s.Contains(a)) return true;
            }
            return false;
        }

        /// <summary>
        /// 是否以某些词结尾
        /// </summary>
        /// <param name="s"></param>
        /// <param name="args"></param>
        /// <returns></returns>
        /// <remarks>2015-2-13 by sutroon</remarks>
        public static bool EndsWithWords(this string s, params string[] args)
        {
            if (string.IsNullOrEmpty(s)) return false;
            foreach (string arg in args)
            {
                if (s.EndsWith(arg))
                {
                    return true;
                }
            }
            return false;
        }

        /// <summary>
        /// 是否以某些词开头
        /// </summary>
        /// <param name="s"></param>
        /// <param name="args"></param>
        /// <returns></returns>
        /// <remarks>2015-2-13 by sutroon</remarks>
        public static bool StartsWithWords(this string s, params string[] args)
        {
            if (string.IsNullOrEmpty(s)) return false;
            foreach (string arg in args)
            {
                if (s.StartsWith(arg))
                {
                    return true;
                }
            }
            return false;
        }

        /// <summary>
        /// 用其他字符串包囊指定字符串
        /// </summary>
        /// <param name="s"></param>
        /// <param name="frontString"></param>
        /// <param name="behindString"></param>
        /// <returns></returns>
        public static string WrapString(this string s, string frontString, string behindString)
        {
            if (s == null || s.Length == 0) return frontString + behindString;
            if (behindString.Length > 0)
            {
                if (!s.EndsWith(behindString)) s += behindString;
            }
            if (frontString.Length > 0)
            {
                if (!s.StartsWith(frontString)) s = frontString + s;
            }
            return s;
        }

        /// <summary>
        /// 字符串转换成标准的SQL参数值
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="s"></param>
        /// <param name="nullvalueable"></param>
        /// <returns></returns>
        public static string ToDbValue<T>(this string s, bool nullvalueable = false)
        {
            if (nullvalueable && s == null) return " is null ";
            if (typeof(T) == typeof(int) || typeof(T) == typeof(short) || typeof(T) == typeof(double))
            {
                return s;
            }
            return string.Format("'{0}'", s);
        }

        /// <summary>
        /// 将货币数值转换为汉字大写金额
        /// </summary>
        /// <param name="s"></param>
        /// <param name="onlyDigit">是否带单位</param>
        /// <returns></returns>
        public static string ToUpperCapital(this string s, bool onlyDigit = true)
        {
            if (s == null || s.Length == 0) return "";
            string sBigUint = "拾佰仟万亿元";
            string sFloatUint = "角分厘零整";
            string sNum = "零壹贰叁肆伍陆柒捌玖";
            if (s.Length == 1) return sNum[s.ToInt()].ToString();
            int b = s.IndexOf('.');
            string n1 = string.Empty, n2 = string.Empty;
            if (b > -1)
            {
                n1 = s.Substring(0, b);
                n2 = s.Substring(b);
            }
            if (n1 == string.Empty) n1 = s;
            StringBuilder sb = new StringBuilder();
            b = 0;
            foreach (char c in n1.ToCharArray())
            {
                if (b == 0 || onlyDigit)
                {
                    sb.Append(sNum[c.ToString().ToInt()]);
                }
                else
                {
                    sb.AppendFormat("{0}{1}", sNum[c.ToString().ToInt()], sBigUint[c.ToString().ToInt() - 1]);
                }
                b++;
            }
            foreach (char c in n2.ToCharArray())
            {
                sb.AppendFormat("{0}{1}", sNum[c.ToString().ToInt()], sFloatUint[c.ToString().ToInt()]);
            }
            return sb.ToString();
        }

        /// <summary>
        /// 字符串转换行数组
        /// </summary>
        /// <param name="s"></param>
        /// <returns></returns>
        public static string[] ToLine(this string s)
        {
            return s.Split(Environment.NewLine.ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
        }

        /// <summary>
        /// 获取文本输入框的最后一行文字
        /// </summary>
        /// <param name="s"></param>
        /// <returns></returns>
        public static string GetLastLine(this string s)
        {
            string[] arr = s.ToLine();
            if (arr.Length == 0) return string.Empty;
            return arr[arr.Length - 1];
        }

        /// <summary>
        /// 移除字符串指定行
        /// </summary>
        /// <param name="s"></param>
        /// <param name="index"></param>
        /// <returns></returns>
        public static string RemoveLine(this string s, int index)
        {
            string[] arr = s.ToLine();
            if (arr.Length == 0) return string.Empty;
            if (index >= arr.Length) index = arr.Length - 1;
            IList<string> list = arr.ToList();
            list.RemoveAt(index);
            return list.ToString(Environment.NewLine);
        }

        /// <summary>
        /// 获取文本中的第一个单词
        /// </summary>
        /// <param name="s"></param>
        /// <returns></returns>
        public static string GetFirstWord(this string s, char splitor = ' ')
        {
            return s.Trim().Split(new char[] { splitor }, StringSplitOptions.RemoveEmptyEntries).First();
        }

        /// <summary>
        /// 显示名称
        /// </summary>
        /// <param name="s"></param>
        /// <param name="values"></param>
        /// <param name="names"></param>
        /// <param name="def"></param>
        /// <returns></returns>
        public static string SwitchName(this string s, string[] values, string[] names, string def)
        {
            int i = ((IList<string>)values).IndexOf(s);
            if (i == -1) return def;
            return names[i];
        }

        #endregion

        #region 字符串语义检测
        /// <summary>
        /// 检测文本中是否包含有待审核的关键词
        /// </summary>
        /// <param name="text"></param>
        /// <param name="censorWords"></param>
        /// <param name="lstHitwords"></param>
        /// <param name="isEnd"></param>
        /// <returns></returns>
        public static bool HasCensorWords(this string text, string censorWords, ref IList<string> lstHitwords, bool isEnd)
        {
            if (text == null || text.Length == 0 || censorWords == null || censorWords.Length == 0) return true;
            bool blnOut = false;
            censorWords = censorWords.Trim('|');
            foreach (string censorWord in censorWords.Split('|'))
            {
                if (text.IndexOf(censorWord) >= 0)
                {
                    blnOut = true;
                    lstHitwords.Add(censorWord);
                    if (isEnd) break;
                }
            }
            return blnOut;
        }
        /// <summary>
        /// 检测文本中是否包含有待审核的关键词
        /// </summary>
        /// <param name="text"></param>
        /// <param name="lstHitwords"></param>
        /// <param name="isEnd"></param>
        /// <returns></returns>
        public static bool HasCensorWords(this string text, ref IList<string> lstHitwords, bool isEnd)
        {
            if (text == null | text.Length == 0) return false;
            string censorWords = "肉棍|阴户|阴唇|淫靡|淫水|阴茎|小穴|阴蒂|法轮大法|李洪志|太比力克|大法弟子|大纪元|真善忍|六四事件|反共|新唐人|无界浏览器|六合彩|特码|成人片|激情图片|激情电影|成人小说|换妻|窃听器|退党|三坐仑|出售枪支|出售假币|监听王|侦探设备|麻醉钢枪|春药|共匪|国际公法|国际公法|活体解剖|活体器官|活体移植|火凤凰|九评|九评共产党|苏家屯集中营|自由门|九评|九评共产党|苏家屯集中营|自由门|自由圣火|自由亚洲电台|宗教迫害|宗教自由|大法|法轮|法一轮|李洪志|大纪元|真善忍|新唐人|六合|阴唇|肉棍|阴户|强奸|淫靡|淫水|阴茎|阴蒂|乱伦|手淫|做鸡|六四事件|江泽民|胡锦涛|罗干|朱镕基|李鹏|江主席|温家宝|迷药|迷魂药|新生网|口交|天安门|共产主义|共产党|中共|反共|台独|达赖|反革命|反华|盗取|绕过封锁|新疆独立|西藏独立|民运分子|打倒|多党执政|专制|国民党|成人小说|成人电影|裸体|激情图片|激情电影|老虎机|代办|办证|刻章|汽车解码器|上分器|偷听器|定位器|警察证|低价出售|最新股民|本科大专|百家乐|国外文凭|染发剂|干扰器|退币器|美国cbh|美国CBH|开发票|发票代理|章刻|票发|件证|套现|欢迎加盟|折批发|零售销售|办证|办证|办证|办证|办.证|刻.章|长期批发|卡西欧|假证|假证|监听|圣美安|假証|假身份证|股民电话|四六级|游戏机|假征|热线|破解技术|无痛丰胸|彩金|赌机|私人侦探|新疆特产|遥控器|苹果机|百家乐|股民资料|学历学位|国外学历|在线观看|破解仪器|赢钱技巧|赌机|六合|老虎机|连线机|手枪|麻醉枪|按摩服务|立体人面|公仔机|冰毒|K粉|摇头丸|双线|学位证|留学论坛|作弊器|按摩美女|上门按摩|上门服务|批发手机|传奇私服|透视|透视眼镜|法门寺|A片|网赚|兼职|游行|租车|假证|代开发票|猎枪|陈水扁|阿莲|阿辉|他妈的|色情|情色|妓女|民主|共产党|我操你|操你妈|傻逼|煞笔|高潮|我日|日我|洗脑|传销|鸡鸡|淫荡|勾引|嘿休|抽插|蜜水|体位|集会|贱人|招聘|自焚|打炮|双飞|丝袜|狼友|去你妈的|护法|三点|偷税|逃税|他妈的|fuck|bitch|傻B|屁|法轮|猪|反共|国民党|共产党|共匪|卖淫|性爱|三级片|鸡巴|我靠|操你|干你|日你|法轮功|你妈|台独|藏独|胡锦涛|温家宝|江泽民|李鹏|陈水扁|马英九|习近平|毛泽东|毛主席|周总理|共产党|台独|疆独|天安门事件";
            return text.HasCensorWords(censorWords, ref lstHitwords, isEnd);
        }
        /// <summary>
        /// 检测文本中是否包含有待审核的关键词
        /// </summary>
        /// <param name="text"></param>
        /// <returns></returns>
        public static bool HasCensorWords(this string text)
        {
            IList<string> lstHitwords = new List<string>();
            return text.HasCensorWords(ref lstHitwords, true);
        }

        #endregion

        #region 字符串加密解密

        /// <summary>
        /// 使用SOMDA加密字符串
        /// <para>不支持双字节字符</para>
        /// </summary>
        /// <param name="s"></param>
        /// <returns></returns>
        public static string SOMDA(this string s)
        {
            if (s == null || s.Length == 0) return "";
            return SOMDAHelper.SOMDA(s);
        }

        /// <summary>
        /// 解密SOMDA方法加密过的字符串
        /// <para>不支持双字节字符</para>
        /// </summary>
        /// <param name="s"></param>
        /// <returns></returns>
        public static string SODEMDA(this string s)
        {
            if (s == null || s.Length == 0) return "";
            return SOMDAHelper.SODEMDA(s);
        }

        /// <summary>
        /// DES加密字符串
        /// <para>支持双字节字符</para>
        /// </summary>
        /// <param name="s"></param>
        /// <returns></returns>
        public static string EncryptByDES(this string s)
        {
            return string.IsNullOrEmpty(s) ? string.Empty : DESHelper.Encode(s);
        }

        /// <summary>
        /// DES解密字符串
        /// <para>支持双字节字符</para>
        /// </summary>
        /// <param name="s"></param>
        /// <returns></returns>
        public static string DeEncryptByDES(this string s)
        {
            return string.IsNullOrEmpty(s) ? string.Empty : DESHelper.Decode(s);
        }
        #endregion

        #region 编码解码

        /// <summary>
        /// UrlEncode编码
        /// </summary>
        /// <param name="s"></param>
        /// <returns></returns>
        /// <remarks>2013-10-31 by sutroon</remarks>
        public static string UrlEncode(this string s)
        {
            return Uri.EscapeUriString(s);
        }
        #endregion

    }
}
